<!--
一个很完善的悬浮球组件，接受一个事件参数，当点击该悬浮球就会触发事件
简单说说过程要解决的许多问题：
 1. 计算位置，性能优化
 2. 适配移动 pc
 3. 到处拖动导致页面文字选中问题
 4. 可以直接拖动到屏幕外问题
 5. 无法展示问题（加个 z-index:100）
 6. 当你移动悬浮球也会触发事件（需要改成只有点击才触发事件，点击拖动不触发事件）
-->
<template>
    <v-menu transition="scale-transition" >
    <template v-slot:activator="{ props }">
    <div
        :style="{ right: `${right}px`, bottom: `${bottom}px` }"
        class="floating-ball"
        v-bind="props"
        @click="handleClick"
        @mousedown="startDrag"
        @touchstart="startTouchDrag">

    </div>
    </template>
    <!-- <v-list> 
        <v-list-item>
           <v-avatar  color="warning" icon="mdi-user"></v-avatar>
        </v-list-item>
        <v-list-item>
           <v-avatar  color="warning" icon="mdi-user"></v-avatar>
        </v-list-item>
    </v-list> -->
    </v-menu>
</template>

<script setup>
import { ref, defineProps } from 'vue';

const props = defineProps({
  onClick: Function
});

const ballSize = 50;
const right = ref(10); // 初始距右边距离
const bottom = ref(10); // 初始距底部距离
const isDragging = ref(false);
let startX, startY, offsetX, offsetY, moved;

const startDrag = (event) => {
  disableTextSelection();
  isDragging.value = true;
  startX = event.clientX;
  startY = event.clientY;
  // 根据悬浮球的当前位置重新计算 offsetX 和 offsetY
  offsetX = (window.innerWidth - right.value - 25) - startX;
  offsetY = (window.innerHeight - bottom.value - 30) - startY;
  moved = false;

  window.addEventListener('mousemove', onMouseMove);
  window.addEventListener('mouseup', stopDrag);
};

const startTouchDrag = (event) => {
  disableTextSelection();
  event.preventDefault();
  const touch = event.touches[0];
  isDragging.value = true;
  startX = touch.clientX;
  startY = touch.clientY;
  // 同样重新计算 offsetX 和 offsetY
  offsetX = (window.innerWidth - right.value - 30) - startX;
  offsetY = (window.innerHeight - bottom.value - 20) - startY;
  moved = false;

  window.addEventListener('touchmove', onTouchMove, { passive: false });
  window.addEventListener('touchend', stopTouchDrag);
};


let animationFrameId = null;

const onMouseMove = (event) => {
  if (!isDragging.value) return;
  if (animationFrameId) cancelAnimationFrame(animationFrameId);

  animationFrameId = requestAnimationFrame(() => {
    updatePosition(event.clientX, event.clientY);
  });
};

const onTouchMove = (event) => {
  event.preventDefault();
  if (!isDragging.value) return;
  const touch = event.touches[0];

  if (animationFrameId) cancelAnimationFrame(animationFrameId);

  animationFrameId = requestAnimationFrame(() => {
    updatePosition(touch.clientX, touch.clientY);
  });
};

const updatePosition = (x, y) => {
  moved = true;
  const halfBallSize = ballSize / 2;
  right.value = Math.max(-halfBallSize, Math.min(window.innerWidth - x - offsetX - halfBallSize, window.innerWidth - halfBallSize));
  bottom.value = Math.max(-halfBallSize, Math.min(window.innerHeight - y - offsetY - halfBallSize, window.innerHeight - halfBallSize));
};



const stopDrag = () => {
  enableTextSelection();
  isDragging.value = false;
  window.removeEventListener('mousemove', onMouseMove);
  window.removeEventListener('mouseup', stopDrag);

  if (!moved && props.onClick) {
    props.onClick();
  }
};

const stopTouchDrag = () => {
  enableTextSelection();
  isDragging.value = false;
  window.removeEventListener('touchmove', onTouchMove);
  window.removeEventListener('touchend', stopTouchDrag);

  if (!moved && props.onClick) {
    props.onClick();
  }
};

function disableTextSelection() {
  document.body.style.userSelect = 'none';
  document.body.style.webkitUserSelect = 'none';  // 针对 Safari 浏览器
  document.body.style.msUserSelect = 'none';      // 针对 IE 浏览器
  document.body.style.mozUserSelect = 'none';     // 针对 Firefox 浏览器
}

function enableTextSelection() {
  document.body.style.userSelect = '';
  document.body.style.webkitUserSelect = '';
  document.body.style.msUserSelect = '';
  document.body.style.mozUserSelect = '';
}

const handleClick = () => {
  // 处理点击逻辑
};
</script>

<style scoped>
.floating-ball {
  width: 50px;
  height: 50px; 
  border-radius: 50%;
  position:fixed;
  z-index: 1000;
  cursor: grab;
  transition: background-color 0.3s ease, box-shadow 0.3s ease;
  z-index: 100;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0); /* 黑色阴影 */
  @apply flex justify-center items-center;
}

.floating-ball:active {
  cursor: grabbing;
}

.floating-ball:hover { 
  background: -webkit-linear-gradient(90deg, #46f8ac,#00dcdd,#44b9df);/* Chrome 10-25, Safari 5.1-6 */                          background: linear-gradient(90deg, #46f8ac,#00dcdd,#44b9df);/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */                                             
  box-shadow: 0 6px 12px 0 rgba(0, 0, 0, 0.1); /* 悬停时的阴影 */
}
</style>